package org.csi.controle.status;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.List;

import org.csi.controle.core.entidade.EnderecoEntrega;
import org.csi.controle.core.entidade.Etapa;
import org.csi.controle.core.serialize.JsonDateDeserializer;
import org.csi.controle.core.to.Login;
import org.csi.controle.core.util.RetornoServico;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

public class Services {

	private static Services instancia;
	
	private String token;
	
	private String URL = "";
	
	private Services(String caminho, String usuario, String senha) throws IOException {
		super();
		this.URL = caminho;
		gerarToken(usuario, senha);
	}
	
	public static Services getInstancia(String caminho, String usuario, String senha) throws IOException {
		if(instancia == null) {
			instancia = new Services(caminho, usuario, senha);
		}
		return instancia;
	}

	@SuppressWarnings("unchecked")
	private void gerarToken(String usuario, String senha) throws IOException {
		Login login = new Login();
		login.setUsuario(usuario);
		login.setSenha(senha);
		login.setManterConectado(true);
		Gson gson = new Gson();
		String jsonRequest = gson.toJson(login);
		String json = request(URL + "login", "POST", "", jsonRequest);
		RetornoServico<String> retorno = gson.fromJson(json, RetornoServico.class);
		token = retorno.getData();
	}
	
	private Long obterIdOriginal(String codigoOs) throws Exception {
		String json = request(URL + "depara/ordemservico/"+codigoOs, "GET", token, null);
		Gson gson = new Gson();
		Type listType = new TypeToken<RetornoServico<Long>>() {}.getType();
		RetornoServico<Long> retorno = gson.fromJson(json, listType);
		if(retorno.getCodigo() != 0) {
			throw new Exception(retorno.getMensagem());
		}
		return retorno.getData();
	}
	
	public void mudarServico(String codigoOs, Integer idEtapa) throws Exception {
		Long idOriginal = obterIdOriginal(codigoOs);
		request(URL + "ordemservico/"+idOriginal+"/historico?proximoIdEtapa="+idEtapa, "POST", token, null);
	}
	
	public void inserirReferencia(String codigoReferencia, Long idEnderecoEntrega) throws Exception {
		request(URL + "ordemservico/endereco/"+idEnderecoEntrega+"/referencia/", "POST", token, codigoReferencia);
	}
	
	public List<Etapa> obterEtapas() throws IOException {
		String json = request(URL + "etapa", "GET", token, null);
		Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new JsonDateDeserializer()).create();
		Type listType = new TypeToken<RetornoServico<List<Etapa>>>() {}.getType();
		RetornoServico<List<Etapa>> retorno = gson.fromJson(json, listType);
		return retorno.getData();		
	}
	
	public List<EnderecoEntrega> obterEnderecos(String codigoOs) throws Exception {
		Long idOriginal = obterIdOriginal(codigoOs);
		String json = request(URL + "ordemservico/"+idOriginal+"/endereco", "GET", token, null);
		Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new JsonDateDeserializer()).create();
		Type listType = new TypeToken<RetornoServico<List<EnderecoEntrega>>>() {}.getType();
		RetornoServico<List<EnderecoEntrega>> retorno = gson.fromJson(json, listType);
		return retorno.getData();
	}
	
	private String request(String urlStr, String method, String token, String jsonPost) throws IOException {
		URL url = new URL(urlStr);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestProperty("token", token);
		connection.setRequestMethod(method);
		connection.setUseCaches(false);
		connection.setDoInput(true);
		connection.setDoOutput(true);
		
		if(jsonPost != null) {
		    connection.setRequestProperty("Content-Type", "application/json");
			DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
			wr.writeBytes(jsonPost);
			wr.flush ();
			wr.close ();
		}
		
		BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream(),Charset.forName("UTF-8")));
		String response = "";
		String line = "";
		while ((line = rd.readLine()) != null) {
			response += line;
		}
		rd.close();
		return response;
	}
	
}